package cn.tedu.store.service.impl;

import java.util.Date;
import java.util.UUID;

import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.tedu.store.entity.User;
import cn.tedu.store.mapper.UserMapper;
import cn.tedu.store.service.IUserService;
import cn.tedu.store.service.ex.InsertException;
import cn.tedu.store.service.ex.PasswordErrorException;
import cn.tedu.store.service.ex.UpdateException;
import cn.tedu.store.service.ex.UserNameDuplicateException;
import cn.tedu.store.service.ex.UserNotFoundException;
/**
 * 处理用户数据的业务层实现类
 * @author Administrator
 *
 */
@Service
public class UserServiceImpl implements IUserService {

	@Autowired
	private UserMapper userMapper;
	
	/**
	 * 用户注册
	 */
	@Override
	public void reg(User user) throws UserNameDuplicateException, InsertException {
		User result = userMapper.findUserByName(user.getUsername());
		if(result != null) {
			//抛出异常，并setMessage 说明异常原因
			throw new UserNameDuplicateException("注册失败，用户名("+user.getUsername()+")已经被占用");
		}
		
		// 生成盐值
		String salt = UUID.randomUUID().toString().toUpperCase();
		user.setSalt(salt);
		
		// 对参数user中的密码加密处理
		String md5Password = getMd5Password(user.getPassword(),salt); 
		
		// 封装盐值和加密后的密码
		user.setPassword(md5Password);
		
		user.setIsDelete(0);
		Date now = new Date();
		//封装4项日志数据
		user.setCreatedUser(user.getUsername());
		user.setCreatedTime(now);
		user.setModefiedUser(user.getUsername());
		user.setModefiedTime(now);
		
		try {
			//执行注册，返回值受影响的行数
			userMapper.addUser(user);
		} catch (Exception e) {
			throw new InsertException("注册失败！插入数据出现未知错误");
		}
	}
	
	
	/**
	 * 用户登录
	 */
	@Override
	public User login(String username, String password) throws UserNotFoundException, PasswordErrorException {
		//根据参数username查询用户数据
		User user = userMapper.findUserByName(username);
		//判断查询结果是否为null
		if(user==null) {
			throw new UserNotFoundException("用户不存在");
		}
		
		//判断查询结果中的isDelete是否为1
		if(user.getIsDelete()==1) {
			throw new UserNotFoundException("用户不存在");
		}
		
		//从查询结果中获取盐值，将参数password和盐值进行加密
		//判断加密后得到的密码与查询结果中的密码是否匹配
		String salt = user.getSalt();
		String md = getMd5Password(password, salt);
		if(!user.getPassword().equals(md)) {
			throw new PasswordErrorException("密码错误");
		}
		
		//用户名和密码都对，则对查询中不想让用户知道的内容设置为null
		user.setPassword(null);
		user.setSalt(null);
		user.setIsDelete(null);
		return user;
		
	}
	
	/**
	 * 修改密码
	 */
	@Override
	public void changePassword(Integer uid, String oldPassword, String newPassword)
			throws UserNotFoundException, PasswordErrorException, UpdateException {
		//根据参数uid查询用户
		User user = userMapper.findByUid(uid);
		//判断查询结果是否为null，是：抛出UserNotFoundException
		if(user==null) {
			throw new UserNotFoundException("用户不存在");
		}
		
		//判断查询结果中的isDelete是否为1，是：抛出UserNotFoundException
		if(user.getIsDelete()==1) {
			throw new UserNotFoundException("用户不存在");
		}
		
		//从查询结果中获取盐值
		String salt = user.getSalt();
		//将参数oldPassword结合盐值加密得到原密码oldMd5Password
		String oldMd5Password = getMd5Password(oldPassword,salt);
		//判断查询结果中的密码与oldMd5Password是否匹配
		if(!user.getPassword().equals(oldMd5Password)) {
			throw new PasswordErrorException("密码错误");
		}
		
		//将参数newPassword结合盐值进行加密得到加密后的新密码newMd5Password
		String newMd5Password = getMd5Password(newPassword,salt);
		
		//从查询结果中获取用户名
		String username = user.getUsername();
		//创建当前时间对象
		Date date = new Date();
		try {
			userMapper.updatePassword(uid, newMd5Password, username, date);
		} catch (Exception e) {
			throw new UpdateException("更新密码异常，稍后重试！");
		}
	}

	
	
	/**
	 * 修改头像
	 */
	@Override
	public void changeAvatar(Integer uid, String avatar) throws UserNotFoundException, UpdateException {
		//根据参数uid查询用户
		User result = userMapper.findByUid(uid);
		//判断查询结果是否为null，是：抛出UserNotFoundException
		if(result==null) {
			throw new UserNotFoundException("用户不存在");
		}
		
		//判断查询结果中的isDelete是否为1，是：抛出UserNotFoundException
		if(result.getIsDelete()==1) {
			throw new UserNotFoundException("用户不存在");
		}
		
		//补全xml映射中的参数
		String modefiedUser = result.getUsername();
		Date modefiedTime = new Date();
		
		Integer rows = userMapper.updateAvatar(uid, avatar, modefiedUser, modefiedTime);
		if(rows!=1) {
			throw new UpdateException("修改头像出现未知异常");
		}
	}
	
	
	
	/**
	 * 修改用户资料
	 */
	@Override
	public void changeInfo(User user) throws UserNotFoundException, UpdateException {
		//先根据uid查询用户
		User result = userMapper.findByUid(user.getUid());
		//判断用户是否存在
		if(result==null) {
			throw new UserNotFoundException("用户不存在");
		}
		
		if(result.getIsDelete()==1) {
			throw new UserNotFoundException("用户不存在");
		}
		
//		user.setModefiedUser(user.getModefiedUser());
//		user.setModefiedTime(new Date());
		
		try {
			Integer rows = userMapper.updateInfo(user);
			System.err.println("rows="+rows);
		} catch (Exception e) {
			throw new UpdateException("修改用户资料异常");
		}
		
	
		
	}

	/**
	 * 根据uid查询用户原来的资料
	 */
	@Override
	public User getByUid(Integer uid) throws UserNotFoundException {
		User result = userMapper.findByUid(uid);
		if(result==null) {
			throw new UserNotFoundException("用户不存在");
		}
		
		if(result.getIsDelete()==1) {
			throw new UserNotFoundException("用户不存在");
		}
		
		//将不必要给用户看的字段设置为null
		result.setPassword(null);
		result.setSalt(null);
		result.setIsDelete(null);
		
		return result;
	}
	
	


	
	
	
	
	

	
	/**
	 * 获取使用MD5摘要算法加密后的密码
	 * @param password 原密码
	 * @param salt 盐值   String salt = UUID.randomUUID().toString().toUpperCase();
	 * @return 加密后的密码
	 */
	private String getMd5Password(String password,String salt) {
		//加密规则，原密码的左右两侧都拼接盐值，并循环加密5次
		String str = salt+password+salt;
		for(int i=0;i<5;i++) {
			str = DigestUtils.md5Hex(str).toUpperCase();
		}
		return str;
	}

}
